/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DataAccess;
import java.io.FileReader;
import java.util.ArrayList;
/**
 *
 * @author Allen
 */

class HmmLexer {
    private int i;
    private char[] content;
    private int length;
    
    protected ArrayList<String> parseTokens(String input){
        ArrayList<String> tokens = new ArrayList<String>();
        content = input.toCharArray();
        length = input.length();

        int start, end, j;
        j = 0;
        while( i < length) {
            passSpace();
            start = i;
            parseSingleToken();
            end = i;

            tokens.add(new String(content, start, end - start));
        }
        
        return tokens;
    }

    private void parseSingleToken(){
        if(!parseDigit()){
            i ++;
            return;
        }
        if(content[i] == '.')
                i ++;
        while(parseDigit()){
            if( content[i] == '.')
                    i ++;
        }
    }

    private void passSpace(){
        while(content[i] == ' ' || content[i] == '\n' || content[i] == '\r'){
            i ++;
        }
    }

    private boolean parseDigit(){
        if(content[i] >= '0' && content[i] <= '9'){
            i ++;
            return true;
        }
        return false;
    }
}
public class HmmParser {
    private int i;
    private int length;
    
    private ArrayList<String> tokens;

    private static final int ROW_NUM = 3;
    private static final int COL_NUM = 3;

    public boolean parse(String input, double[][] T, double [][] O){
        i = 0;

        HmmLexer hl = new HmmLexer();
        tokens = hl.parseTokens(input);
        length = tokens.size();
        
        if(!parseT(T))
            return false;
        if(!parseO(O))
            return false;
        return true;
    }

    private boolean parseDouble(double row[], int i_row){
        if(i >= length )
            return false;
        String d = tokens.get(i);
        try {
            double result = Double.parseDouble(d);
            row[i_row] = result;
        } catch (Exception e){
            return false;
        }
        i ++;
        return true;
    }

    private boolean parseMatrix(double[][] m){
        if(!parseString("{"))
            return false;
        int j  = 0;
        for(j = 0; j < ROW_NUM; j ++) {
            if(!parseRow(m[j]))
                return false;
            if(!parseString(","))
                return false;
        }

        if(!parseString("}"))
            return false;

        return true;
    }

    private boolean parseT(double [][] T){
        if(!parseString("T"))
            return false;
        if(!parseString("="))
            return false;

        if(!parseMatrix(T))
            return false;

        if(!parseString(";"))
            return false;

        return true;
    }

    private boolean parseRow(double[] row){
        
        if(!parseString("{"))
            return false;

        int j = 0;
        for (j = 0; j < COL_NUM - 1; j ++){
            if(!parseDouble(row, j))
                return false;
            if(!parseString(","))
                return false;
        }

        if(!parseDouble(row, j))
            return false;
        if(!parseString("}"))
            return false;

        return true;
    }
    private boolean parseO(double[][] O){
        if(!parseString("O"))
            return false;
        if(!parseString("="))
            return false;
        if(!parseMatrix(O))
            return false;
        if(!parseString(";"))
            return false;

        return true;
    }

    private boolean parseString(String str){
        if(i >= length )
            return false;
        String token = tokens.get(i);
        if(token.compareTo(str) != 0)
            return false;

        i ++;
        return true;
    }


    static public void main ( String[] args) {
        HmmParser hr = new HmmParser();
                
        try {
            char data[] = new char[1024];
            FileReader fr = new FileReader("data_test/test.txt");
            int length = fr.read(data);
            fr.close();
            double [][] T = new double[3][3];
            double [][] O = new double[3][3];
            hr.parse(new String(data, 0, length), T, O);
        } catch (Exception e) { }
    }
}
